/**
 * 
 */
package org.valire.usermanagement;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.valire.usermanagement.beans.NodeAccessPermission;
import org.valire.usermanagement.beans.Role;
import org.valire.usermanagement.beans.User;
import org.valire.usermanagement.services.NodeAccessPermissionService;
import org.valire.usermanagement.services.RolesService;
import org.valire.usermanagement.services.UserService;

/**
 * @author Oren Zamir
 * 
 */
public class UserManagementFacadeImpl implements UserManagementFacade {

	private static Logger logger = LoggerFactory.getLogger(UserManagementFacadeImpl.class);
	
	private UserService userService;
	
	private RolesService rolesService = null;
	
	private NodeAccessPermissionService napService;
	
	Map<String,Integer>		indexByName 	= null;
	Map<Integer,UserDto>	usersByIndex 	= null;
	
	public void setUserService(UserService userService) {
		this.userService = userService;
	}
	
	public void setNapService(NodeAccessPermissionService napService) {
		this.napService = napService;
	}

	public void setRolesService(RolesService rolesService) {
		this.rolesService = rolesService;
	}

	public void setCacheForUsersDto() {
		if (indexByName == null) indexByName = new HashMap<String,Integer>();
		if (usersByIndex == null) usersByIndex = new HashMap<Integer,UserDto>();
		
		indexByName.clear();
		usersByIndex.clear();
		
		List<User> allUsers = userService.getAllUsers();
		for (User user : allUsers) {
			UserDto userDto = UmDtoConversions.convert(user);
			indexByName.put(user.getUserName(), user.getId());
			usersByIndex.put(user.getId(), userDto);
		}
	}
	
	@Override
	public void permit(Integer userId, Integer categoryId){
		User user = userService.getUser(userId);
		if(user == null){
			throw new IllegalArgumentException("No user with id:"+userId);
		}
		Set<User> ul = new HashSet<User>();
		ul.add(user);
		
		NodeAccessPermission nap = new NodeAccessPermission();
		nap.setUsers(ul);
		nap.setNodeReference(categoryId);
		napService.createNAP(nap);
		logger.info("Permitted access to {} for user {}", categoryId, user.getUserName());
	}

	@Override
	public RoleDto getRole(String roleName){
		Role role = rolesService.getRole(roleName);
		return UmDtoConversions.convert(role);
	}
	
	@Override
	public void createUser(UserDto newUser) {
		userService.createUser(UmDtoConversions.convert(newUser));
		setCacheForUsersDto();
		logger.info("Created user '{}'", newUser.getUserName());
	}

	@Override
	public void removeUser(UserDto user) {
		userService.removeUser(UmDtoConversions.convert(user));
		setCacheForUsersDto();
	}

	@Override
	public void removeUser(String userName) {
		User user = userService.getUser(userName);
		if(user == null)
			throw new IllegalArgumentException("No such user: "+userName);
		userService.removeUser(user);
		setCacheForUsersDto();
	}

	@Override
	public void updateUser(UserDto user) {
		userService.updateUser(UmDtoConversions.convert(user));
		setCacheForUsersDto();
	}

	@Override
	public UserDto getUser(Integer id) {
		if (usersByIndex == null) setCacheForUsersDto();
		return usersByIndex.get(id);
	}
	
	@Override
	public UserDto getUser(String userName) {
		if (usersByIndex == null) setCacheForUsersDto();
		User user = userService.getUser(userName);
		return UmDtoConversions.convert(user);
	}

	@Override
	public List<UserDto> getAllUsers() {
		if (usersByIndex == null) setCacheForUsersDto();
		
		List<UserDto> l = new ArrayList<UserDto>();
		l.addAll(usersByIndex.values());
		return l;
	}

	@Override
	public String resetPassword(UserDto User) {
		return null;
	}

}
